package com.ai.service.cms.sensitiveword.impl;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;

import com.ai.common.utils.cache.redis.shared.RedisUtils;
import com.ai.manager.edu.sensitiveword.SensitiveWordManager;
import com.ai.service.cms.sensitiveword.SensitiveWordService;

@Service("sensitiveWordService")
public class SensitiveWordServiceImpl implements SensitiveWordService {
    // 敏感词
    @Resource
    private SensitiveWordManager sensitiveWordManager;

    // Redis缓存
    @Resource
    private RedisUtils redisUtils;

    private Map sensitiveWordMap = null;

    private static final int MIN_MATCH_TYPE = 1;
    private static final int MAX_MATCH_TYPE = 2;

    // 敏感词缓存Key
    private static final String SENSITIVE_KEY = "edu-cms-sensitive-key";

    /**
     * 是否包含敏感词
     * 
     * @author zhoukai5
     * @param txt
     * @param matchType
     *
     */

    public boolean isContaintSensitiveWord(String txt, int matchType) {
        // 初始化敏感词Map
        this.initKeyWords();
        boolean flag = false;
        for (int i = 0; i < txt.length(); i++) {
            int matchFlag = this.CheckSensitiveWord(txt, i, matchType);
            if (matchFlag > 0) {
                flag = true;
            }
        }
        return flag;
    }

    /**
     * 获取敏感词集合（已去重）
     * 
     * @author zhoukai5
     * @param txt
     * @param matchType
     *
     */
    public Set<String> getSensitiveWord(String txt, int matchType) {
        // 初始化敏感词Map
        this.initKeyWords();
        Set<String> sensitiveWordList = new HashSet<String>();

        for (int i = 0; i < txt.length(); i++) {
            int length = CheckSensitiveWord(txt, i, matchType);
            if (length > 0) {
                sensitiveWordList.add(txt.substring(i, i + length));
                i = i + length - 1;
            }
        }
        return sensitiveWordList;
    }

    /**
     * 用特定字符替换敏感词
     * 
     * @author zhoukai5
     * @param txt
     * @param matchType
     * @param replaceChar
     */
    public String replaceSensitiveWord(String txt, int matchType, String replaceChar) {
        // 初始化敏感词Map
        this.initKeyWords();
        String resultTxt = txt;
        Set<String> set = getSensitiveWord(txt, matchType);
        Iterator<String> iterator = set.iterator();
        String word = null;
        String replaceString = null;
        while (iterator.hasNext()) {
            word = iterator.next();
            replaceString = getReplaceChars(replaceChar, word.length());
            resultTxt = resultTxt.replaceAll(word, replaceString);
        }

        return resultTxt;
    }

    /**
     * check是否为敏感词
     * 
     * zhoukai5
     * 
     * @param txt
     * @param beginIndex
     * @param matchType
     *
     */
    private int CheckSensitiveWord(String txt, int beginIndex, int matchType) {
        boolean flag = false;
        int matchFlag = 0;
        char word = 0;
        Map nowMap = sensitiveWordMap;
        for (int i = beginIndex; i < txt.length(); i++) {
            word = txt.charAt(i);
            nowMap = (Map) nowMap.get(word);
            if (nowMap != null) {
                matchFlag++;
                if ("1".equals(nowMap.get("isEnd"))) {
                    flag = true;
                    if (MIN_MATCH_TYPE == matchType) {
                        break;
                    }
                }
            }
            else {
                break;
            }
        }
        if (matchFlag < 2 || !flag) {
            matchFlag = 0;
        }
        return matchFlag;
    }

    /**
     * Description ： 这里记述method的说明<br>
     * 
     * zhoukai5
     * 
     * @param replaceChar
     * @param length
     */
    private String getReplaceChars(String replaceChar, int length) {
        String resultReplace = replaceChar;
        for (int i = 1; i < length; i++) {
            resultReplace += replaceChar;
        }

        return resultReplace;
    }

    private void initKeyWords() {
        Set<String> keyWordSet = (Set<String>) redisUtils.smembers(SENSITIVE_KEY);
        if (CollectionUtils.isEmpty(keyWordSet)) {
            List<String> wordList = sensitiveWordManager.findAllSensitiveWord();
            String[] wordArray = new String[wordList.size()];
            Set<String> wdSet = new HashSet();
            for (int i = 0; i < wordList.size(); i++) {
                wordArray[i] = wordList.get(i);
                wdSet.add(wordList.get(i));
            }
            keyWordSet = wdSet;
            redisUtils.sadd(SENSITIVE_KEY, wordArray);
            redisUtils.expire(SENSITIVE_KEY, 60 * 60 * 4);
        }

        sensitiveWordMap = new HashMap(keyWordSet.size());
        String key = null;
        Map nowMap = null;
        Map<String, String> newWorMap = null;
        //
        Iterator<String> iterator = keyWordSet.iterator();
        while (iterator.hasNext()) {
            key = iterator.next();
            nowMap = sensitiveWordMap;
            for (int i = 0; i < key.length(); i++) {
                char keyChar = key.charAt(i);
                Object wordMap = nowMap.get(keyChar);

                if (wordMap != null) {
                    nowMap = (Map) wordMap;
                }
                else {
                    newWorMap = new HashMap<String, String>();
                    newWorMap.put("isEnd", "0");
                    nowMap.put(keyChar, newWorMap);
                    nowMap = newWorMap;
                }

                if (i == key.length() - 1) {
                    nowMap.put("isEnd", "1");
                }
            }
        }
    }

}
